﻿using Castle.DynamicProxy;

namespace Luka;

/// <summary>
/// 事务Aop
/// </summary>
public class UseTranAOP : IInterceptor, IScoped
{
    /// <summary>
    /// 工作单元
    /// </summary>
    private readonly IUnitOfWork _unitOfWork;

    /// <summary>
    /// 构造函数
    /// </summary>
    public UseTranAOP(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    /// <summary>
    /// 实现拦截器
    /// </summary>
    /// <param name="invocation"></param>
    public void Intercept(IInvocation invocation)
    {
        var method = invocation.MethodInvocationTarget ?? invocation.Method;
        if (method.IsDefined(typeof(UseTranAttribute), false))
        {
            try
            {
                //开启事务
                _unitOfWork.BeginTran();
                //执行方法
                if (invocation.Method.IsAsyncMethod())
                {
                    invocation.ReturnValue = invocation.ProceedAsync();
                }
                else
                {
                    invocation.Proceed();
                }
                //提交事务
                _unitOfWork.CommitTran();
            }
            catch (Exception)
            {
                //回滚事务
                _unitOfWork.RollbackTran();
                throw;
            }
            finally
            {
                //关闭事务
                _unitOfWork.Close();
            }
        }
    }
}